﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using AllInOnePluginBL.Helpers;

namespace AllInOnePluginBL.FileHostingExtractors
{
    /// <summary>
    /// Summary description for VideoBBExtractor
    /// </summary>
    public class VideoBBExtractor : IFileHostingExtractor
    {
        private const string CONTROL_URI = "http://videobb.com/player_control/settings.php?v={0}&em=TRUE&fv=v1.2.72";
        private const string URL_TEMPLATE = @"http://www.videobb.com/e/{0}";
        private const string URL_REGEX = "http://www.videobb.com/e/([A-Za-z0-9]+)|http://videobb.com/e/([A-Za-z0-9]+)";
        private const string URL_REGEX_2 = "http://www.videobb.com/.*?v=([A-Za-z0-9]+)|http://videobb.com/.*?v=([A-Za-z0-9]+)";
        private const string MOVIE_URL = "http://www.videobb.com/e/";
        private const string TOKEN = "\"token1\":\"([A-Za-z0-9+/]{4})*(|[A-Za-z0-9+/]{2}(==|[A-Za-z0-9+/]=))";
        private const string SETTING_REG_EX = "videobb.com.*?setting=(.+?)\"";
        private const string SETTING_FULL_REG_EX = "<param name=\"movie\" value=\"http://www.videobb.com/player/player.swf\\?setting=(.+?)\" >";
        private const string NEX_REG_EX = @"http://(www.)?videobb.com/(e/|video/|watch_video.php\?v=)[0-9A-Za-z]+"; //TODO:Replace
        private const string REFERER = "http://www.videobb.com/e/{0}";
        private const string HOST = "www.videobb.com";

        public List<string> GetMovieUrls(string content)
        {
            var movieUrls = new List<string>();
            var exp = new Regex(URL_REGEX, RegexOptions.IgnoreCase);
            var matches = exp.Matches(content);
            if (matches.Count == 0)
            {
                //fixed as bug
                matches = Regex.Matches(content, SETTING_FULL_REG_EX, RegexOptions.IgnoreCase);
                foreach (Match match in matches)
                {
                    var base64String = match.Groups[1].Value;
                    var decodeString = Utils.DecodeUrl(base64String);
                    var videoCode = Regex.Match(decodeString, URL_REGEX_2, RegexOptions.IgnoreCase).Groups[1].Value;
                    if (!string.IsNullOrEmpty(videoCode))
                    {
                        var movieUrl = string.Format(URL_TEMPLATE, videoCode);
                        if (!movieUrls.Contains(movieUrl))
                        {
                            movieUrls.Add(movieUrl);
                        }
                    }
                }
            }
            else
            {
                foreach (Match match in matches)
                {
                    if (match.Success)
                    {
                        var movieUrl = match.Value;
                        if (!movieUrls.Contains(movieUrl))
                        {
                            movieUrls.Add(movieUrl);
                        }
                    }
                }
            }
            return movieUrls;
        }

        public VideoResult ExtractMovieUrl(string movieUrl)
        {
            var movieCode = movieUrl.Replace(MOVIE_URL, string.Empty);
            var content = Utils.GetPage(string.Format(CONTROL_URI, movieCode), Encoding.Default, REFERER, string.Empty);

            if (content.Contains("This video was either deleted by the user or in breach of a copyright holder"))
            {
                throw new Exception("This video was either deleted by the user or in breach of a copyright holder");
            }
            
            var match = Regex.Match(content, TOKEN, RegexOptions.IgnoreCase);
            if (!match.Success)
            {
                throw new Exception("Cant find videoBB link");
            }

            var convertedBytes = Convert.FromBase64String(match.Value.Replace("\"token1\":\"", string.Empty));

            const string videoTitleRegEx = "\"video\":{\"title\":\"(.+?)\"";
            match = Regex.Match(content, videoTitleRegEx, RegexOptions.IgnoreCase);
            return match.Success ? 
                new VideoResult(Encoding.UTF8.GetString(convertedBytes), match.Groups[1].Value, true) : 
                new VideoResult(Encoding.UTF8.GetString(convertedBytes), true);
        }

        public bool IsContainVideoLink(string content)
        {
            var match = Regex.Match(content, URL_REGEX, RegexOptions.IgnoreCase);
            if(!match.Success)
            {
                match = Regex.Match(content, SETTING_REG_EX, RegexOptions.IgnoreCase);
            }
            return match.Success;
        }
    }
}